@file:OptIn(ExperimentalLayoutApi::class)

package toy.keli.edic.view

import android.util.Log
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.LocalTextStyle
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.AnnotatedString.Range
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Popup
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import toy.keli.edic.data.GlobalVal
import toy.keli.edic.data.config.MenuConf
import toy.keli.edic.ui.home.viewMode
import toy.keli.edic.ui.listenbook.ListenBookData
import toy.keli.edic.ui.main.components.Display.sp2dp
import toy.keli.edic.ui.main.extend.annotatedText
import java.util.Stack


@OptIn(ExperimentalLayoutApi::class)
@Composable
fun RichText(text: String, fonts: RichTextFonts?, onWordClick: (word:String) -> String?={""} ,onPopInfoClick:(word:String)->Unit={},isVisible:Boolean=true,defStyle:TextStyle= LocalTextStyle.current
        ,searchKey:String,selected:Boolean=false,searchSelectedIndex:Int=0
            ,content: @Composable () -> Unit ={}
) {
//    SelectableText(text=text,style=defStyle){
//        Log.d("RichText: ",it)
//    }
//    if(true) return

//    val regex = Regex("\\w+|\\s+|[^\\w\\s]")
//    val textParts = regex.findAll(text).map { it.value }.toList()
    var isParsing by remember { mutableStateOf(false) }

    var textParts by remember { mutableStateOf<List<String>>(emptyList()) }
    // 异步分割，避免阻塞UI
    LaunchedEffect(isVisible,text) {
            delay(200)
            if (isVisible && !isParsing) {
                isParsing = true // 标记为“正在解析”，避免重复触发
                // 切换到IO线程执行耗时操作
                withContext(Dispatchers.IO) {
                    textParts = splitTextManually(text)
                    isParsing = false
                }
            }
    }


    val pw = remember { PopUpWindow() }
    var boxTop = 0f
    Box(modifier = Modifier
        //页面渲染完成之后获取弹框位置
        .onGloballyPositioned { coordinates ->
            val textPosition = coordinates.positionInRoot()
            boxTop = textPosition.y
    }) {
        //添加弹框
        pw.add()
        FlowRow(
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp),
//            verticalArrangement = Arrangement.spacedBy(sp2dp((defStyle.lineHeight.value-defStyle.fontSize.value/2f).toInt())),
//            verticalArrangement = Arrangement.spacedBy(4.dp),
        ) {
            if(textParts.size==0){
                content()
            }else {
                var index =0
                var startPos = listOf<Range<SpanStyle>>()
                var annotatedText:AnnotatedString? = null
                if(searchKey.isNotEmpty()) {
                    annotatedText = annotatedText(text,searchKey, selected = selected,searchSelectedIndex = searchSelectedIndex)
                    startPos = annotatedText.spanStyles.filter { it.item.color != Color.Unspecified }
                    index=0
                }

                //输出文本
                textParts.forEach { part ->
                    //弹框位置
                    val popupPosition = remember { mutableStateOf(IntOffset(0, 0)) }
                    if (part.trim().length == 0) {
                        Text(part,style = defStyle)
                    } else {
                        //获取字体信息
                        val rtf = if (fonts == null) RichTextFont() else fonts.selectByText(part)
                        val fc = remember { mutableStateOf(rtf.color) }
                        var bgColor = rtf.bgColor
                        //根据颜色实现颜色的标注
                        if (startPos.isNotEmpty()) {
                            val spanStyle = startPos.filter { it.start <= index }.last()
                            val start = spanStyle.start
                            val end = start + searchKey.length
                            if (index in start..end) {
                                bgColor = spanStyle.item.color
                            }
                            index += part.length
                        }
                        Text(
                            text = part,
                            style = defStyle,
                            color = fc.value,
                            fontSize = rtf.fontSize,
                            fontFamily = rtf.fontFamily,
                            fontStyle = rtf.fontStyle,
                            fontWeight = rtf.fontWeight,
                            modifier = Modifier //.wrapContentWidth()
                                .background(bgColor)
                                //页面渲染完成之后获取弹框位置
                                .onGloballyPositioned { coordinates ->
                                    val textPosition = coordinates.positionInRoot()
                                    val textSize = coordinates.size
                                    popupPosition.value = IntOffset(
                                        x = (textPosition.x + textSize.width / 2 - 150).toInt(),
                                        y = (textPosition.y - boxTop - 100).toInt()
                                    )
                                }
                                .clickable { //单击弹出弹框
                                    fc.value = Color.Red
                                    if (!Regex("^[\\w`]+$").matches(part)) return@clickable
                                    var tip = onWordClick(part)
                                    if (tip != null && tip.length > 0) {
                                        pw.show(popupPosition.value, tip, onClink = {
                                            onPopInfoClick(part)
                                        }, onLongClick = {
                                            //切换到学习视图
                                            GlobalVal.wordViewModel.searcher(tip)
                                            viewMode = MenuConf.mode.wordStudy
                                        })
                                    }
                                }
                        )
                    }
                }
            }
        }
    }

}


class PopUpWindow {
        var intOffset by mutableStateOf(IntOffset.Zero)
        var showPopup by mutableStateOf(false)
        var popupContent by mutableStateOf("中文")
        var popOnClick:()->Unit = {};
        var popOnLongClick:()->Unit = {};

        fun show(offset: IntOffset,text:String,onClink:()->Unit = {},onLongClick:()->Unit ={}) {
            popupContent = text
            intOffset = offset;
            showPopup = true;
            popOnClick = onClink
            popOnLongClick = onLongClick
        }

        @OptIn(ExperimentalFoundationApi::class)
        @Composable
        @Preview
        fun add(bubbleCornerRadius:Int = 10,
                bubbleBackgroundColor:Color = Color.Gray,
                bubbleBorderColor:Color = Color.Black
        ) {
            if (showPopup) {
                Popup(
                    onDismissRequest = { showPopup = false },
                    alignment = Alignment.TopStart,
                    offset = intOffset,
                ) {
                    Box(
                        modifier = Modifier
                            .alpha(0.9f)
                            .background(
                                color = bubbleBackgroundColor,
                                shape = RoundedCornerShape(bubbleCornerRadius)
                            )
                            .border(
                                width = 1.dp,
                                color = bubbleBorderColor,
                                shape = RoundedCornerShape(bubbleCornerRadius)
                            )
                            .padding(12.dp)
                            .combinedClickable(onClick = {
                                showPopup = false
                                popOnClick()
                            }, onLongClick = {
                                showPopup = false
                                popOnLongClick()
                            })
                    ) {
                        Text(
                            text = popupContent,
                            textAlign = TextAlign.Center,
                            fontSize = 14.sp
                        )

                        // 气泡底部的小箭头
//                        Box(
//                            modifier = Modifier
//                                .size(12.dp)
//                                .background(bubbleBackgroundColor)
//                                .border(1.dp, bubbleBorderColor)
//                                .rotate(45f)
//                                .align(Alignment.BottomCenter)
//                                .offset(y = 6.dp)
//                        )
                    }
                }
            }
        }
}



fun splitTextManually(text: String): List<String> {
    if (text.isEmpty()) return emptyList()

    val result = arrayListOf<String>()
    val current = StringBuilder()
    var currentType: CharType? = null // 当前片段的类型

    for (c in text) {
        val type = when {
            c.isLetterOrDigit() || c == '_' -> CharType.WORD // 匹配 \\w
            c.isWhitespace() -> CharType.SPACE // 匹配 \\s
            else -> CharType.OTHER // 匹配 [^\\w\\s]
        }

        if (currentType == null) {
            // 初始化第一个字符
            current.append(c)
            currentType = type
        } else if (currentType == type && type != CharType.OTHER) {
            // 同类型且非OTHER，继续拼接（OTHER只能单个字符）
            current.append(c)
        } else {
            // 类型变化，提交当前片段并开始新片段
            result.add(current.toString())
            current.clear()
            current.append(c)
            currentType = type
        }
    }

    // 添加最后一个片段
    if (current.isNotEmpty()) {
        result.add(current.toString())
    }

    return result
}

// 字符类型枚举
private enum class CharType {
    WORD, SPACE, OTHER
}
